package com.opentool.dns;
import com.opentool.web.service.ILocalDnsService;
import com.opentool.web.spring.SpringUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.handler.codec.dns.*;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
public class DnsProxy {
    private  Channel proxyChannel;
    private  Channel clientChannel;
    private  InetSocketAddress clientRecipient;
    private  InetSocketAddress clientSender;

    public InetSocketAddress getClientRecipient() {
        return clientRecipient;
    }

    public void setClientRecipient(InetSocketAddress clientRecipient) {
        this.clientRecipient = clientRecipient;
    }

    public InetSocketAddress getClientSender() {
        return clientSender;
    }

    public void setClientSender(InetSocketAddress clientSender) {
        this.clientSender = clientSender;
    }

    public void init(String dnsHost, int dnsPort,final DnsProxy dnsProxy,final Channel clientChannel){
        Bootstrap bootstrap=new Bootstrap();
        NioEventLoopGroup workerGroup=new NioEventLoopGroup();
        bootstrap.group(workerGroup)
                .channel(NioDatagramChannel.class)
                .option(ChannelOption.SO_BROADCAST, true)
                .handler(new ChannelInitializer<NioDatagramChannel>() {
                    @Override
                    protected void initChannel(NioDatagramChannel ch)throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new DatagramDnsQueryEncoder());
                        pipeline.addLast(new DatagramDnsResponseDecoder());
                        pipeline.addLast(new DnsProxyHandler(dnsProxy,clientChannel));
                    }
                });
        this.proxyChannel = bootstrap.connect(dnsHost,dnsPort).syncUninterruptibly().channel();
        this.clientChannel=clientChannel;
    }

    public void sendDnsQuery(DatagramDnsQuery query) throws UnknownHostException {
        ILocalDnsService localDnsService= SpringUtil.getBean(ILocalDnsService.class);
        String dnsServer=localDnsService.queryDnsServer();
        if(this.proxyChannel!=null){
            query.retain();
            InetSocketAddress dnsAddr=new InetSocketAddress(dnsServer,53);
            DatagramDnsQuery newQuery = new DatagramDnsQuery(null, (InetSocketAddress) dnsAddr, query.id());
            DefaultDnsQuestion dnsQuestion = query.recordAt(DnsSection.QUESTION);
            newQuery.addRecord(DnsSection.QUESTION,dnsQuestion);
            this.proxyChannel.writeAndFlush(newQuery);
        }
    }
}
